package com.zb.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.zb.constant.WorkConstant;
import com.zb.entity.*;
import com.zb.extend.WorkSlaConditionExtend;
import com.zb.extend.WorkSlaExtend;
import com.zb.order.service.WorkSlaUtilService;
import com.zb.service.*;
import com.zb.sms.entity.ReceiveVo;
import com.zb.utils.ZbDateConvertUtil;
import com.zb.utils.ZbDateUtil;
import com.zb.view.ViewNetworkEmpAccount;
import com.zb.view.ViewNetworkEmpDetail;
import com.zb.vo.OrderSlaSelectVo;
import com.zb.vo.OrderSlaVo;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author WEN
 * @Date 2024/3/9 0009
 **/
@Service
public class WorkSlaUtilServiceImpl implements WorkSlaUtilService {
    @Resource
    private ZjWorkSlaService workSlaService;
    @Resource
    private ZjWorkDispatchNetworkService workDispatchNetworkService;
    @Resource
    private ZjWorkDispatchEngineerService workDispatchEngineerService;
    @Resource
    private ZjAccountService accountService;
    @Resource
    private ViewNetworkEmpDetailService viewNetworkEmpDetailService;
    @Resource
    private ViewNetworkEmpAccountService viewNetworkEmpAccountService;

    // 获取工单Sla信息
    @Override
    public List<OrderSlaVo> getOrderSlaInfo(List<OrderSlaSelectVo> slaSelectVos) {
        if (CollectionUtil.isEmpty(slaSelectVos)) {
            return new ArrayList<>();
        }
        List<WorkSlaExtend> workSlaExtendList = workSlaService.getWorkSlaByModuleIds(slaSelectVos.stream().map(OrderSlaSelectVo::getModuleId).distinct().toList(), false);
        if (CollectionUtil.isEmpty(workSlaExtendList)) {
            return new ArrayList<>();
        }
        // 待服务商接单的工单
        List<Long> serviceOrderIds = slaSelectVos.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_2).map(OrderSlaSelectVo::getWorkId).toList();
        // 查询服务商的待接单的工单
        List<ZjWorkDispatchNetwork> workDispatchNetworks = workDispatchNetworkService.getWaitReceiveOrderByWorkIds(serviceOrderIds);
        // 服务中的工单ID
        serviceOrderIds = slaSelectVos.stream().filter(f -> f.getStatus() == WorkConstant.WORK_STATUS_3).map(OrderSlaSelectVo::getWorkId).toList();
        // 查询工程师的工单
        List<ZjWorkDispatchEngineer> workDispatchEngineers = workDispatchEngineerService.getByWorkIds(serviceOrderIds);

        List<OrderSlaVo> orderSlaVos = new ArrayList<>();
        OrderSlaVo orderSlaVo = null;
        WorkSlaExtend slaExtend = null;
        ZjWorkDispatchNetwork dispatchNetwork = null;
        ZjWorkDispatchEngineer dispatchEngineer = null;
        Date currentTime = null;
        WorkSlaConditionExtend conditionExtend = null;
        for (OrderSlaSelectVo vo : slaSelectVos) {
            slaExtend = workSlaExtendList.stream().filter(f -> f.getModuleIds().stream().anyMatch(f2 -> Objects.equals(f2, vo.getModuleId()))).findFirst().orElse(null);
            if (null == slaExtend) {
                continue;
            }
            // 当前时间
            currentTime = new Date();
            // 如果启用时间范围，则判断sla时间范围
            if (slaExtend.getDateType() == 2 && !(currentTime.after(slaExtend.getStartTime()) && currentTime.before(slaExtend.getEndTime()))) {
                continue;
            }
            orderSlaVo = new OrderSlaVo(vo.getWorkId());
            orderSlaVo.setAssignServiceEmp(vo.isAssignServiceEmp());
            orderSlaVo.setNodeTimeoutLength("");
            // 工单未派单
            if (vo.getStatus() == WorkConstant.WORK_STATUS_1) {
                conditionExtend = slaExtend.getWorkSlaConditionExtends().stream().filter(f -> f.getType() == 2).findFirst().orElse(null);
                if (null == conditionExtend || !conditionExtend.getEnabled()) {
                    continue;
                }
                // 判断是否超时未派单
                if (currentTime.after(DateUtils.addHours(vo.getCreateTime(), conditionExtend.getAgeingTime()))) {
                    orderSlaVo.setType(2);
                    orderSlaVo.setNodeTimeout(true);
                    orderSlaVo.setNodeTimeoutLength(ZbDateUtil.getTimeLength(DateUtils.addHours(vo.getCreateTime(), conditionExtend.getAgeingTime()), currentTime));
                    orderSlaVos.add(orderSlaVo);
                }
                continue;
            }
            // 待服务商接单
            if (vo.getStatus() == WorkConstant.WORK_STATUS_2) {
                dispatchNetwork = workDispatchNetworks.stream().filter(f -> Objects.equals(f.getWorkId(), vo.getWorkId())).findFirst().orElse(null);
                if (null == dispatchNetwork) {
                    continue;
                }
                conditionExtend = slaExtend.getWorkSlaConditionExtends().stream().filter(f -> f.getType() == 3).findFirst().orElse(null);
                if (null == conditionExtend || !conditionExtend.getEnabled()) {
                    continue;
                }
                // 判断是否超时未接单
                if (currentTime.after(DateUtils.addHours(dispatchNetwork.getDispatchTime(), conditionExtend.getAgeingTime()))) {
                    orderSlaVo.setType(3);
                    orderSlaVo.setNodeTimeout(true);
                    orderSlaVo.setNodeTimeoutLength(ZbDateUtil.getTimeLength(DateUtils.addHours(dispatchNetwork.getDispatchTime(), conditionExtend.getAgeingTime()), currentTime));
                    orderSlaVos.add(orderSlaVo);
                }
                continue;
            }
            // 非服务中的不再执行
            if (vo.getStatus() != WorkConstant.WORK_STATUS_3) {
                continue;
            }
            dispatchEngineer = workDispatchEngineers.stream().filter(f -> Objects.equals(f.getWorkId(), vo.getWorkId())).findFirst().orElse(null);
            if (null == dispatchEngineer) {
                continue;
            }
            // 待接单
            if (dispatchEngineer.getStatus() == 1) {
                conditionExtend = slaExtend.getWorkSlaConditionExtends().stream().filter(f -> f.getType() == 4).findFirst().orElse(null);
                if (null == conditionExtend || !conditionExtend.getEnabled()) {
                    continue;
                }
                // 判断是否超时未接单
                if (currentTime.after(DateUtils.addHours(ZbDateConvertUtil.dateStrToDate(dispatchEngineer.getDispatchTime()), conditionExtend.getAgeingTime()))) {
                    orderSlaVo.setType(4);
                    orderSlaVo.setNodeTimeout(true);
                    orderSlaVo.setNodeTimeoutLength(ZbDateUtil.getTimeLength(DateUtils.addHours(ZbDateConvertUtil.dateStrToDate(dispatchEngineer.getDispatchTime()), conditionExtend.getAgeingTime()), currentTime));
                    orderSlaVos.add(orderSlaVo);
                }
                continue;
            }
            // 超时未拨打电话
            if (dispatchEngineer.getCallPhoneQty() == 0) {
                conditionExtend = slaExtend.getWorkSlaConditionExtends().stream().filter(f -> f.getType() == 5).findFirst().orElse(null);
                if (null == conditionExtend || !conditionExtend.getEnabled()) {
                    continue;
                }
                // 判断是否超时
                if (currentTime.after(DateUtils.addHours(ZbDateConvertUtil.dateStrToDate(dispatchEngineer.getReceivingOrderTime()), conditionExtend.getAgeingTime()))) {
                    orderSlaVo.setType(5);
                    orderSlaVo.setNodeTimeout(true);
                    orderSlaVo.setNodeTimeoutLength(ZbDateUtil.getTimeLength(DateUtils.addHours(ZbDateConvertUtil.dateStrToDate(dispatchEngineer.getReceivingOrderTime()), conditionExtend.getAgeingTime()), currentTime));
                    orderSlaVos.add(orderSlaVo);
                }
                continue;
            }
            // 超时未预约
            if (dispatchEngineer.getStatus() == WorkConstant.DISPATCH_ENGINEER_STATUS_2 && null == dispatchEngineer.getReservationDate()) {
                conditionExtend = slaExtend.getWorkSlaConditionExtends().stream().filter(f -> f.getType() == 6).findFirst().orElse(null);
                if (null == conditionExtend || !conditionExtend.getEnabled()) {
                    continue;
                }
                // 判断是否超时
                if (currentTime.after(DateUtils.addHours(dispatchEngineer.getGmtUpdate(), conditionExtend.getAgeingTime()))) {
                    orderSlaVo.setType(6);
                    orderSlaVo.setNodeTimeout(true);
                    orderSlaVo.setNodeTimeoutLength(ZbDateUtil.getTimeLength(DateUtils.addHours(dispatchEngineer.getGmtUpdate(), conditionExtend.getAgeingTime()), currentTime));
                    orderSlaVos.add(orderSlaVo);
                }
                continue;
            }
            // 超时未上门/签到
            if (dispatchEngineer.getStatus() == WorkConstant.DISPATCH_ENGINEER_STATUS_2 && !dispatchEngineer.getSignIn()) {
                conditionExtend = slaExtend.getWorkSlaConditionExtends().stream().filter(f -> f.getType() == 7).findFirst().orElse(null);
                if (null == conditionExtend || !conditionExtend.getEnabled()) {
                    continue;
                }
                // 判断是否超时
                if (currentTime.after(DateUtils.addHours(dispatchEngineer.getGmtUpdate(), conditionExtend.getAgeingTime()))) {
                    orderSlaVo.setType(7);
                    orderSlaVo.setNodeTimeout(true);
                    orderSlaVo.setNodeTimeoutLength(ZbDateUtil.getTimeLength(DateUtils.addHours(dispatchEngineer.getGmtUpdate(), conditionExtend.getAgeingTime()), currentTime));
                    orderSlaVos.add(orderSlaVo);
                }
            }
        }
        return orderSlaVos;
    }

    // 获取工单Sla信息
    @Override
    public OrderSlaVo getOrderSlaInfo(OrderSlaSelectVo slaSelectVo) {
        List<OrderSlaSelectVo> slaSelectVos = new ArrayList<>();
        slaSelectVos.add(slaSelectVo);
        List<OrderSlaVo> orderSlaInfo = getOrderSlaInfo(slaSelectVos);
        return CollectionUtil.isEmpty(orderSlaInfo)? null : orderSlaInfo.get(0);
    }

    // 获取提醒人员信息
    @Override
    public void getReminderEmpInfo(List<ZjAccount> accountList, List<ViewNetworkEmpDetail> networkEmpDetails, List<ViewNetworkEmpAccount> networkEmpAccountList,
                                   List<Integer> remindEmpTypes, List<Long> remindEmpIds, List<ZjWorkOrder> orderList) {
        // 工单客服/指定人员
        if (remindEmpTypes.stream().anyMatch(f -> f == 1 || f == 4)) {
            if (null == remindEmpIds) {
                remindEmpIds = new ArrayList<>();
            }
            remindEmpIds.addAll(orderList.stream().filter(f -> f.getEmpId() != null && f.getEmpId() != 0).map(ZjWorkOrder::getEmpId).distinct().toList());
            if (CollectionUtil.isNotEmpty(remindEmpIds)) accountList.addAll(accountService.getByIds(remindEmpIds.stream().distinct().toList()));
        }
        // 服务商负责人
        if (remindEmpTypes.stream().anyMatch(f -> f == 2)) {
            List<Long> networkIds = orderList.stream().filter(f -> null != f.getNetworkId() && f.getNetworkId() != 0).map(ZjWorkOrder::getNetworkId).distinct().toList();
            if (CollectionUtil.isNotEmpty(networkIds)) networkEmpDetails.addAll(viewNetworkEmpDetailService.getManagerByNetworkIds(networkIds));
        }
        // 工程师
        if (remindEmpTypes.stream().anyMatch(f -> f == 3)) {
            List<Long> networkEmpIds = orderList.stream().filter(f -> f.getNetworkEmpId() != null && f.getNetworkEmpId() != 0).map(ZjWorkOrder::getNetworkEmpId).distinct().toList();
            if (CollectionUtil.isNotEmpty(networkEmpIds)) networkEmpAccountList.addAll(viewNetworkEmpAccountService.getByIds(networkEmpIds));
        }
    }

    @Override
    public ReceiveVo getReceiveEmpInfo(Integer remindEmpType, List<ZjAccount> accountList, List<ViewNetworkEmpDetail> networkEmpDetails, List<ViewNetworkEmpAccount> networkEmpAccountList, ZjWorkOrder order) {
        if (remindEmpType == 1) {
            ZjAccount account = accountList.stream().filter(f -> Objects.equals(f.getId(), order.getEmpId())).findFirst().orElse(null);
            if (null != account) {
                return new ReceiveVo(account.getPhone(), account.getName());
            }
            return null;
        }
        if (remindEmpType == 2) {
            ViewNetworkEmpDetail viewNetworkEmpDetail = networkEmpDetails.stream().filter(f -> Objects.equals(f.getNetworkId(), order.getNetworkId())).findFirst().orElse(null);
            if (null != viewNetworkEmpDetail) {
                return new ReceiveVo(viewNetworkEmpDetail.getAccountPhone(), viewNetworkEmpDetail.getAccountName());
            }
            return null;
        }
        if (remindEmpType == 3) {
            ViewNetworkEmpAccount viewNetworkEmpAccount = networkEmpAccountList.stream().filter(f -> Objects.equals(f.getId(), order.getNetworkEmpId())).findFirst().orElse(null);
            if (null != viewNetworkEmpAccount) {
                return new ReceiveVo(viewNetworkEmpAccount.getPhone(), viewNetworkEmpAccount.getName());
            }
            return null;
        }
        return null;
    }

}
